package com.xy6.jvm.io;

import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PushbackReader;
import java.io.StringReader;
import java.io.StringWriter;

/**
 * java io类操作示例
 * <pre>
 * 流的概念和作用
 * 流：代表任何有能力产出数据的数据源对象或者是有能力接受数据的接收端对象。<Thinking in Java>
 * 流的本质：数据传输，根据数据传输特性将流抽象为各种类，方便更直观的进行数据操作。
 * 流的作用：为数据源和目的地建立一个输送通道。
 * 
 * Java中将输入输出抽象称为流，就好像水管，将两个容器连接起来。
 * 流是一组有顺序的，有起点和终点的字节集合，是对数据传输的总称或抽象。即数据在两设备间的传输称为流。
 * 
 * https://www.cnblogs.com/ylspace/p/8128112.html
 * </pre>
 * 
 * @author zhang
 * @since 2018-04-22
 */
public class TestIO2 {

	public static void printStream(){
		try (FileOutputStream fos = new FileOutputStream("D:\\1.txt"); 
				PrintStream ps = new PrintStream(fos);) {
			// 输出一行，立刻将内容写入文件
			ps.println("普通字符串\n");
			ps.println(new TestIO2());
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println("print done");
	}
	
	public static void stringNode(){
		String str = "天王盖地虎\n"
				 + "宝塔镇河妖\n";
		char[] buf = new char[32];
		int hasRead = 0;
		// StringReader将以string字符串为节点读取数据
		try( StringReader sr = new StringReader(str)){
			while((hasRead = sr.read(buf)) > 0){
				System.out.println(new String(buf, 0, hasRead));
			}
		} catch(IOException e){
			e.printStackTrace();
		}
		
		// 由于String是一个不可变类，因此创建StringWriter时，实际上是以一个StringBuffer作为输出节点
		try(StringWriter sw = new StringWriter()){
			sw.write("黑夜给了我黑色的眼睛\n");
			sw.write("我却用它寻找光明\n");
			System.out.println(sw.toString());
		} catch(IOException e){
			e.printStackTrace();
		}
	}
	
	public static void keyIn(){
		// InputStreamReader是从byte转为char的桥梁
		try (InputStreamReader reader = new InputStreamReader(System.in);
				// BufferedReader()是char类型输入的包装类
				BufferedReader br = new BufferedReader(reader);) {
			String line = null;
			while ((line = br.readLine()) != null) {
				if ("exit".equals(line)) {
					break;
				}
				System.out.println(line);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static void pushback(){
		try (PushbackReader pr = new PushbackReader(new FileReader(
				"E:/program/oschina/jdkdemo/jdkdemo/src/com/xy6/jvm/io/TestIO2.java"), 256)) {
			char[] buf = new char[64];
			String lastContent = "";
			int hasRead = 0;
			while((hasRead = pr.read(buf)) > 0){
				String content = new String(buf, 0, hasRead);
				int targetIndex = 0;
				if((targetIndex = (lastContent + content).indexOf("targetIndex = (lastContent + content)")) > 0){
					pr.unread((lastContent + content).toCharArray());
					if(targetIndex > 32){
						buf = new char[targetIndex];
					}
					pr.read(buf, 0, targetIndex);
					System.out.println(new String(buf, 0, targetIndex));
					System.exit(0);
				} else {
					System.out.println(lastContent);
					lastContent = content;
				}
			}
		} catch(IOException e){
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
//		printStream();
//		System.out.println("------------------");
//		stringNode();
//		System.out.println("------------------");
//		keyIn();
//		System.out.println("------------------");
		pushback();
	}

}
